<script setup lang='ts' name="direct-order">
import type { VxeTableInstance } from 'vxe-table'

import { useGetOrderAddressInfo, useGetOrderAddressList, useGetPc, useJcOrderMetaAddOrUpdateOrder, useJcOrderMetaAuditOrder, useJcOrderMetaExportOrder, useJcOrderMetaSubmitToAudit } from '@fl/api/purchase'
import { SearchForm, SearchTable } from '@fl/components'
import { cloneDeep } from 'lodash-es'
import NP from 'number-precision'
import { useRouter } from 'vue-router'

import AuditOrder from './audit-order.vue'
import IsAudit from './is-audit.vue'

const props = withDefaults(defineProps<{
    agreementMetaInfo?: any
    orderData?: any
}>(), {
    agreementMetaInfo: () => { },
    orderData: () => { },
})

const isAuditVisible = ref(false)

const auditOrderVisible = ref(false)

const orderId = defineModel('orderId')

const { back, replace } = useRouter()

const cascader = ref()

const { agreementMetaInfo, orderData } = toRefs(props)

const showProductSelect = defineModel<boolean>('showProductSelect', { required: true })

const list = defineModel<any[]>('list')

const { data: pcaData, isLoading: pcaLoading } = useGetPc()

const { data: consigneeData, isLoading: consigneeLoading } = useGetOrderAddressList()

const { isPending: saveLoading, mutate: saveMutate } = useJcOrderMetaAddOrUpdateOrder()

const { isPending: submitLoading, mutate: submitMutate } = useJcOrderMetaSubmitToAudit()

const { isPending: exportLoading, mutate: exportMutate } = useJcOrderMetaExportOrder()

const { isPending: auditOrderLoading, mutate: auditOrderMutate } = useJcOrderMetaAuditOrder()

const detailForm = ref()

const submitForm = ref()

const pcaOptions = computed(() => {
    return pcaData.value ? pcaData.value : []
})

const consigneeOptions = computed(() => {
    return consigneeData.value
        ? consigneeData.value.map((item: any) => {
            return {
                label: item.consignee,
                value: item.id,
            }
        })
        : []
})

const projectNameOptions = computed(() => {
    return consigneeData.value
        ? consigneeData.value.map((item: any) => {
            return {
                label: item.projectName,
                value: item.id,
            }
        })
        : []
})

const isEdit = computed(() => {
    // 无订单id 订单状态为1
    return Boolean(orderId.value) === false || [1].includes(orderData.value?.orderStatus)
})

const showAudit = computed(() => {
    // 状态为待审批并且有审批权限
    return orderData.value?.hasAuditAuth === 1 && orderData.value?.orderStatus === 2
})

const showExport = computed(() => Boolean(orderId.value))

const cancelText = computed(() => orderId.value ? '返回' : '上一步')

const isLoading = computed(() => consigneeLoading.value || pcaLoading.value)

const gridOptions = reactive<any>({
    border: true,
    columnConfig: {
        resizable: true,
    },
    columns: [
        { slots: { default: 'info' }, title: '商品详情', width: 400 },
        { field: 'brand', title: '品牌' },
        { field: 'model', title: '型号' },
        { slots: { default: 'unit' }, title: '单价/单位' },
        { slots: { default: 'quantity' }, title: '本次下单数量', width: 120 },
        {
            slots: { default: 'total' },
            title: '总价',
        },
    ],
    data: [],
    editConfig: {
        mode: 'row',
        showStatus: true,
        trigger: 'manual',
    },
    height: 530,
    keepSource: true,
    loading: false,
    showOverflow: false,
})

const tableRef = ref<VxeTableInstance<any>>()

const detail = ref<any>({
    address: '',
    cityId: '',
    consignee: '',
    id: '',
    phone: '',
    projectName: '',
})

const defaultDetail = cloneDeep(detail.value)

const childIsAudit = ref<InstanceType<typeof IsAudit> | null>(null)

const childAuditOrder = ref<InstanceType<typeof AuditOrder> | null>(null)

const id = computed(() => {
    return detail.value.id
})

const isSend = ref(false)

const { data: infoData } = useGetOrderAddressInfo(id, isSend)

const defaultDetailColumns = [
    {
        defaultProp: 'projectName',
        editProp: 'id',
        fieldProps: computed(() => ({
            onChange: () => {
                isSend.value = true
            },
            onClear: () => {
                detail.value = defaultDetail
            },
        })),
        label: '项目名称',
        labelWidth: '100px',
        options: projectNameOptions,
        prop: isEdit.value ? 'id' : 'projectName',
        type: 'select',
        valueType: '',
    },
    {
        defaultProp: 'consignee',
        editProp: 'id',
        fieldProps: computed(() => ({
            onChange: () => {
                isSend.value = true
            },
            onClear: () => {
                detail.value = defaultDetail
            },
        })),
        label: '收货人',
        labelWidth: '100px',
        options: consigneeOptions,
        prop: isEdit.value ? 'id' : 'consignee',
        type: 'select',
        valueType: '',
    },
    {
        defaultProp: 'phone',
        editProp: 'phone',
        label: '收货人电话',
        labelWidth: '100px',
        prop: 'phone',
        type: 'input',
        valueType: '',
    },
    {
        defaultProp: 'cityId',
        editProp: 'cityId',
        label: '收货地址',
        prop: 'cityId',
    },
    {
        defaultProp: 'address',
        editProp: 'address',
        hasLabel: true,
        label: '详细地址',
        labelWidth: '100px',
        prop: 'address',
        type: 'input',
        valueType: '',
    },
]

const detailColumns = computed(() => {
    const result = cloneDeep(defaultDetailColumns)
    result.forEach((item) => {
        item.valueType = isEdit.value ? item.type : 'text'
        item.prop = isEdit.value ? item.editProp : item.defaultProp
    })
    return result
})

const submitInfo = ref<any>({
    installCost: 0,
    orderName: '',
    otherCost: 0,
    selectTime: [],
    transportationCost: 0,
})

const maxNumber = 999999.99

const defaultSubmitColumns = [
    {
        colProps: {
            span: 8,
        },
        label: '订单名称',
        labelWidth: '100px',
        prop: 'orderName',
        type: 'input',
        valueType: '',
    },
    {
        colProps: {
            span: 8,
        },
        fieldProps: { max: maxNumber, min: 0, precision: 2 },
        label: '运输费',
        labelWidth: '100px',
        prop: 'transportationCost',
        type: 'input-number',
        valueType: '',
    },
    {
        colProps: {
            span: 8,
        },
        fieldProps: {
            endPlaceholder: '请选择结束时间',
            startPlaceholder: '请选择开始时间',
            type: 'daterange',
            valueFormat: 'YYYY-MM-DD',
        },
        label: '期望交货日期',
        labelWidth: '120px',
        prop: 'selectTime',
        type: 'date-picker',
        valueType: '',
    },
    {
        colProps: {
            span: 8,
        },
        fieldProps: { max: maxNumber, min: 0, precision: 2 },
        label: '安装费',
        labelWidth: '100px',
        prop: 'installCost',
        type: 'input-number',
        valueType: '',
    },
    {
        colProps: {
            span: 8,
        },
        fieldProps: { max: maxNumber, min: 0, precision: 2 },
        label: '其他费用',
        labelWidth: '100px',
        prop: 'otherCost',
        type: 'input-number',
        valueType: '',
    },
]

const submitColumns = computed(() => {
    const result = cloneDeep(defaultSubmitColumns)
    result.forEach((item) => {
        item.valueType = isEdit.value ? item.type : 'text'
    })
    return result
})

function cancel() {
    if (orderId.value) {
        replace('/purchase-pages/purchase-order-management/contract')
    }
    else {
        showProductSelect.value = true
    }
}

const submitParams = computed(() => {
    return {
        addressId: detail.value.id,
        agreementCode: agreementMetaInfo.value.agreementCode,
        agreementId: agreementMetaInfo.value.id,
        agreementName: agreementMetaInfo.value.agreementName,
        cityId: detail.value.cityId,
        deliveryAddress: detail.value.address,
        expectedDeliveryEndDate: submitInfo.value.selectTime?.[1],
        expectedDeliveryStartDate: submitInfo.value.selectTime?.[0],
        id: orderId.value ?? '',
        installCost: submitInfo.value.installCost,
        orderName: submitInfo.value.orderName,
        otherCost: submitInfo.value.otherCost,
        partyA: agreementMetaInfo.value.partyA,
        partyAId: agreementMetaInfo.value.partyAId,
        partyB: agreementMetaInfo.value.partyB,
        partyBId: agreementMetaInfo.value.partyBId,
        products: gridOptions.data,
        projectName: detail.value.projectName,
        purchaser: detail.value.consignee,
        purchaserPhone: detail.value.phone,
        transportationCost: submitInfo.value.transportationCost,
    }
})

async function save() {
    const detailValid = await detailForm.value.formInstance.formInstance.validate()
    const submitValid = await submitForm.value.formInstance.formInstance.validate()
    if (detailValid && submitValid) {
        const pathLabels = cascader.value.getCheckedNodes()[0].pathLabels
        const pathValues = cascader.value.getCheckedNodes()[0].pathValues
        const params = {
            ...submitParams.value,
            city: pathLabels?.[1],
            province: pathLabels?.[0],
            provinceId: pathValues?.[0],
        }
        saveMutate(params, {
            onSuccess: () => {
                ElMessage.success('操作成功')
                back()
            },
        })
    }
}

async function submit() {
    const detailValid = await detailForm.value.formInstance.formInstance.validate()
    const submitValid = await submitForm.value.formInstance.formInstance.validate()
    if (detailValid && submitValid) {
        isAuditVisible.value = true
    }
}

function isAuditSubmit(val: any) {
    const pathLabels = cascader.value.getCheckedNodes()[0].pathLabels
    const pathValues = cascader.value.getCheckedNodes()[0].pathValues
    const params = {
        ...submitParams.value,
        ...val,
        city: pathLabels?.[1],
        province: pathLabels?.[0],
        provinceId: pathValues?.[0],
        submitType: orderId.value ? 2 : 1, // 下单页面提交订单(没有orderId则为下单页面提交)

    }
    submitMutate(params, {
        onSuccess: () => {
            ElMessage.success('操作成功')
            childIsAudit.value!.cancel()
            back()
        },
    })
}

function exportOrder() {
    if (orderId.value) {
        exportMutate(String(orderId.value), {
            onSuccess: (res: any) => {
                const objectUrl = URL.createObjectURL(res)
                location.href = objectUrl
                URL.revokeObjectURL(objectUrl)
            },
        })
    }
}

function auditOrder() {
    auditOrderVisible.value = true
}

function auditOrderSubmit(val: any) {
    const params = {
        ...val,
        id: orderId.value,
    }
    auditOrderMutate(params, {
        onSuccess: () => {
            ElMessage.success('操作成功')
            childAuditOrder.value!.cancel()
            back()
        },
    })
}

const rules = {
    address: [{ message: '请输入详细地址', required: true, trigger: 'blur' }],
    cityId: [{ message: '请选择收货地址', required: true, trigger: 'blur' }],
    id: [{ message: '请选择收货人-项目名称', required: true, trigger: 'blur' }],
    orderName: [{ message: '请输入订单名称', required: true, trigger: 'blur' }],
    phone: [
        { message: '请输入收货人电话', required: true, trigger: 'blur' },
        {
            message: '手机号码格式不正确',
            pattern: /^1[3-9]\d{9}$/,
            trigger: 'blur',
        },
    ],
    selectTime: [{ message: '请选择期望交货日期', required: true, trigger: 'blur' }],
}

function handleChange(val) {
    console.log(val)
}

watchEffect(() => {
    if (list.value)
        gridOptions.data = cloneDeep(list.value)
})

watchEffect(() => {
    if (infoData.value) {
        detail.value = {
            ...infoData.value,
        }
    }
})

watchEffect(() => {
    if (orderData.value) {
        detail.value = {
            address: orderData.value.deliveryAddress,
            cityId: orderData.value.cityId,
            consignee: orderData.value.purchaser,
            id: isEdit.value ? orderData.value.addressId : '',
            phone: orderData.value.purchaserPhone,
            projectName: orderData.value.projectName,
        }
        submitInfo.value = {
            installCost: orderData.value.installCost,
            orderName: orderData.value.orderName,
            otherCost: orderData.value.otherCost,
            selectTime: isEdit.value ? [orderData.value.expectedDeliveryStartDate, orderData.value.expectedDeliveryEndDate] : `${orderData.value.expectedDeliveryStartDate} - ${orderData.value.expectedDeliveryEndDate}`,
            transportationCost: orderData.value.transportationCost,
        }
    }
})
</script>

<template>
    <ElSkeleton v-if="isLoading"
                animated
    />

    <div v-else>
        <el-card mb-20>
            <div class="info-title">
                订单信息
            </div>

            <SearchForm ref="detailForm"
                        v-model="detail"
                        :rules="isEdit ? rules : ''"
                        :columns="detailColumns"
                        :has-footer="false"
            >
                <template #plus-field-cityId>
                    <el-cascader v-if="isEdit"
                                 ref="cascader"
                                 v-model="detail.cityId"
                                 :options="pcaOptions"
                                 :props=" { children: 'children', emitPath: false, label: 'name', value: 'code' }"
                                 @change="handleChange"
                    />

                    <span v-else>
                        {{ `${orderData?.province}-${orderData?.city}` }}
                    </span>
                </template>
            </SearchForm>
        </el-card>

        <el-card mb-20>
            <SearchTable v-bind="gridOptions"
                         ref="tableRef"
                         class="mb-20"
            >
                <template #info="{ row }">
                    <div class="pd-info">
                        <el-image v-if="row.skuUrl"
                                  style="width: 120px; height: 120px"
                                  class="mr-10"
                                  :src="row.skuUrl?.split(';')?.[0]"
                                  :preview-src-list="row.skuUrl?.split(';')"
                                  fit="cover"
                        />

                        <div class="pd-desc">
                            <p class="truncate w-full"
                               :title="row?.productName"
                            >
                                {{ row.productName }}
                            </p>

                            <p class="truncate w-full"
                               :title="row?.skuName"
                            >
                                规格：{{ row?.skuName }}
                            </p>

                            <p class="truncate w-full"
                               :title="row?.category"
                            >
                                品类：{{ row?.category }}
                            </p>

                            <p class="truncate w-full"
                               :title="orderData?.partyB"
                            >
                                供应商：{{ orderData?.partyB }}
                            </p>

                            <p class="truncate w-full"
                               :title="row?.attribute"
                            >
                                规格属性：{{ row?.attribute }}
                            </p>
                        </div>
                    </div>
                </template>

                <template #quantity="{ row }">
                    <el-input-number v-model="row.quantity"
                                     size="small"
                                     style="width: 100px;"
                                     :disabled="true"
                    />
                </template>

                <template #total="{ row }">
                    <span style="color: red;">￥{{ NP.round(row.agreementPrice * (row.quantity ?? 0), 2) }}元</span>
                </template>

                <template #unit="{ row }">
                    <span style="color: red;">￥{{ row.agreementPrice }}元/{{ row?.unit }}</span>
                </template>
            </SearchTable>

            <SearchForm ref="submitForm"
                        v-model="submitInfo"
                        :rules="isEdit ? rules : ''"
                        :columns="submitColumns"
                        :has-footer="false"
            >
                <template #plus-field-transportationCost>
                    <el-input-number v-if="isEdit"
                                     v-model="submitInfo.transportationCost"
                                     :max="maxNumber"
                                     :min="0"
                                     :precision="2"
                                     class="w-full!"
                    />

                    <span v-else>
                        {{ orderData?.transportationCost }}元
                    </span>
                </template>

                <template #plus-field-installCost>
                    <el-input-number v-if="isEdit"
                                     v-model="submitInfo.installCost"
                                     :max="maxNumber"
                                     :min="0"
                                     :precision="2"
                                     class="w-full!"
                    />

                    <span v-else>
                        {{ orderData?.installCost }}元
                    </span>
                </template>

                <template #plus-field-otherCost>
                    <el-input-number v-if="isEdit"
                                     v-model="submitInfo.otherCost"
                                     :max="maxNumber"
                                     :min="0"
                                     :precision="2"
                                     class="w-full!"
                    />

                    <span v-else>
                        {{ orderData?.otherCost }}元
                    </span>
                </template>
            </SearchForm>
        </el-card>

        <el-card>
            <div class="flex gap-15 justify-center">
                <el-button @click="cancel">
                    {{ cancelText }}
                </el-button>

                <el-button v-if="isEdit"
                           :loading="saveLoading"
                           @click="save"
                >
                    保存
                </el-button>

                <el-button v-if="showExport"
                           :loading="exportLoading"
                           @click="exportOrder"
                >
                    导出订单
                </el-button>

                <el-button v-if="showAudit"
                           @click="auditOrder"
                >
                    审批
                </el-button>

                <el-button v-if="isEdit"
                           type="primary"
                           @click="submit"
                >
                    确认订单
                </el-button>
            </div>
        </el-card>
    </div>

    <IsAudit ref="childIsAudit"
             v-model:visible="isAuditVisible"
             v-model:loading="submitLoading"
             @submit="isAuditSubmit"
    />

    <AuditOrder ref="childAuditOrder"
                v-model:visible="auditOrderVisible"
                v-model:loading="auditOrderLoading"
                @submit="auditOrderSubmit"
    />
</template>

<style lang="less" scoped>
.info-title {
    font-size: 16px;
    font-weight: 600;
    line-height: 60px;
    margin-bottom: 20px;
}

.footer-btn {
    text-align: center;
}

.pd-info {
    display: flex;
    // width: 100%;
    padding: 10px 0;

    img {
        width: 175px;
        margin-right: 20px;
    }

    .pd-desc {
        flex: 1;
        width: 1px;
        color: #9da1ae;
        text-align: left;
        display: flex;
        flex-direction: column;
        justify-content: space-between;

        p:first-child {
            font-size: 15px;
            color: #000;
            font-weight: 600;
        }
    }
}
</style>
